local source_ChatFrame_OnEvent

local ChatFrames = {}
ChatFrames[1] = ChatFrame1
ChatFrames[3] = ChatFrame3
ChatFrames[4] = ChatFrame4
ChatFrames[5] = ChatFrame5
ChatFrames[6] = ChatFrame6
ChatFrames[7] = ChatFrame7

local SimilarKeywords = {}
SimilarKeywords["zg"] = { "zg", "zug", "祖格", "龙虎金" }
SimilarKeywords["bwl"] = { "bwl", "黑翼" }
SimilarKeywords["klz"] = { "klz", "卡拉赞" }
SimilarKeywords["naxx"] = { "naxx", "纳克萨玛斯" }
SimilarKeywords["fx"] = { "fx", "废墟" }
SimilarKeywords["stsm"] = { "stsm", "斯坦索姆" }

local function print(str, skip, chatFrame)
    if str == nil or strlen(str) == 0 then
        return
    end
	local prefix = "|cFF00CCCCwcf:|r"
    if (skip) then
		prefix = ""
	end
    (chatFrame or DEFAULT_CHAT_FRAME):AddMessage(prefix .. str)
end

local function split(str)
	local result = {}
	for match in string.gmatch(str, "([^,|]+)") do
		local cleaned = strtrim(match)
		table.insert(result, cleaned)
	end
	return result
end


local f = CreateFrame("Frame", "wienChatFilterFrame", UIParent)
f:SetWidth(130)
f:SetHeight(30)
f:SetBackdrop({
    bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
    edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
    tile = true,
    tileSize = 16,
    edgeSize = 16,
    insets = {
        left = 4,
        right = 4,
        top = 4,
        bottom = 4
    }
})
f:SetBackdropColor(0, 0, 0, 0.5)
f:SetBackdropBorderColor(1, 1, 1, 1)
f:SetPoint("CENTER", UIParent, "CENTER")
f:SetMovable(true)
f:EnableMouse(true)
f:RegisterForDrag("LeftButton")
f:SetScript("OnDragStart", function()
	if not IsShiftKeyDown() then
		return
	end
	this:StartMoving()
end)
f:SetScript("OnDragStop", function()
    this:StopMovingOrSizing()
end)


local text = f:CreateFontString(nil, "OVERLAY", "GameFontNormal")
text:SetAllPoints()
text:SetTextColor(0, 191, 255)
text:SetJustifyH("CENTER")

local function WriteText()
	local prefix = "消息过滤器: "
	text:SetText(prefix .. (wienChatFilterDB.enabled and "|cFF00FF00启用" or "|cFFFF0000停止"))
end



local function AddKeyword(keywords, ignore)
	if (keywords == nil or strlen(keywords) == 0) then
		return
	end
	local keywordsStore = (ignore ~= nil and ignore) and wienChatFilterDB.ignoreKeywords or wienChatFilterDB.subscribeKeywords
	local keywordArray = split(string.lower(keywords))
	for _, keyword in keywordArray do
		local isCanAdd = true
		for _, item in keywordsStore do
			if item == keyword then
				print("词已存在:" .. keyword)
				isCanAdd = false
				break
			end
		end
		if isCanAdd then
			table.insert(keywordsStore, keyword)
			print("添加词:" .. keyword)
		end
	end	
end

local function DelKeyword(keywords, ignore)
	if (keywords == nil or strlen(keywords) == 0) then
		return
	end
	local keywordsStore = (ignore ~= nil and ignore) and wienChatFilterDB.ignoreKeywords or wienChatFilterDB.subscribeKeywords
	local keywordArray = split(string.lower(keywords))
	for _, keyword in keywordArray do
		for index, item in keywordsStore do
			if item == keyword then
				table.remove(keywordsStore, index)
				print("删除词:" .. keyword)
				break
			end
		end
	end
end


local function Init()
    if (wienChatFilterDB == nil) then wienChatFilterDB = {} end
	if (wienChatFilterDB.ignoreKeywords == nil) then wienChatFilterDB.ignoreKeywords = {} end
	if (wienChatFilterDB.subscribeKeywords == nil) then wienChatFilterDB.subscribeKeywords = {} end
	if (wienChatFilterDB.debug == nil) then wienChatFilterDB.debug = false end
	if (wienChatFilterDB.enabled == nil) then wienChatFilterDB.enabled = false end
end

local function Reset(ignore)
	if (ignore ~= nil and ignore) then
		wienChatFilterDB.ignoreKeywords = {}
	else
		wienChatFilterDB.subscribeKeywords = {}
	end
	print(((ignore ~= nil and ignore) and "过滤词表" or "订阅词表") .. "重置成功")
end

local function List(ignore)
	print("----" .. ((ignore ~= nil and ignore) and "过滤" or "订阅") .. "词列表----")
	if ignore ~= nil and ignore then
		print(table.concat(wienChatFilterDB.ignoreKeywords, ","), true)
	else
		local result = ""
		for _, item in wienChatFilterDB.subscribeKeywords do
			local str = ""
			if SimilarKeywords[item] == nil then
				str = item
			else
				local SimilarStr = item .. "("
				for __, keyword in SimilarKeywords[item] do
					SimilarStr = SimilarStr .. keyword .. ","
				end
				SimilarStr = string.sub(SimilarStr, 1, string.len(SimilarStr) - 1)
				str = SimilarStr .. ")"
			end
			result = result .. str .. ","
		end
		result = string.sub(result, 1, string.len(result) - 1)
		print(result, true)
	end
    print("----------------")
end


local help = {
	"/wienchatfilter 或者 /wcf <命令> [参数]",
	"命令:",
	" - t - 总开关:开启或关闭",
	" - s - 查看当前插件状态",
	" - aik [关键词] - 添加忽略消息关键词,多个词用[,或|]分隔",
	" - dik [关键词] - 删除忽略消息关键词,多个词用[,或|]分隔",
	" - rik - 重置忽略消息关键词列表",
	" - ask [关键词] - 添加订阅消息关键词,多个词用[,或|]分隔",
	" - dsk [关键词] - 删除订阅消息关键词,多个词用[,或|]分隔",
	" - rsk - 重置订阅消息关键词列表"
}

local function Help()
	print("帮助")
	for _, helpline in help do
		print(helpline)
	end
end

local function Debug()
	if wienChatFilterDB.debug then
		wienChatFilterDB.debug = false
	else
		wienChatFilterDB.debug = true
	end
end

local function Toggle()
	if wienChatFilterDB.enabled then
		wienChatFilterDB.enabled = false
	else
		wienChatFilterDB.enabled = true
	end
end

local function Status()
    print(wienChatFilterDB.enabled and "启用" or "停止")
    if wienChatFilterDB.debug then print("启动debug模式") end
	List(true)
	List()
end

local function SlashCommand(message)
	local paramstr = message
	local cmd = paramstr
	local index = strfind(cmd, " ")
	if (index) then
		cmd = strsub(cmd, 1, index - 1)
		paramstr = strsub(paramstr, index + 1)
	else
		paramstr = ""
	end

	if (not cmd) then
		return nil
	end

	if cmd == "aik" then AddKeyword(paramstr, true) Status()
	elseif cmd == "dik" then DelKeyword(paramstr, true) Status()
	elseif cmd == "rik" then Reset(true) Status()
	elseif cmd == "ask" then AddKeyword(paramstr) Status()
	elseif cmd == "dsk" then DelKeyword(paramstr) Status()
	elseif cmd == "rsk" then Reset() Status()
	elseif cmd == "s" then Status()
	elseif cmd == "t" then Toggle() Status() WriteText()
	elseif cmd == "debug" then Debug() Status()
	else Help() end
end

SLASH_WIENCHATFILTER1 = "/wcf"
SLASH_WIENCHATFILTER2 = "/wienchatfilter"
SlashCmdList["WIENCHATFILTER"] = SlashCommand


local function IgnoreMessage(event)
	if not wienChatFilterDB.enabled then
		return false
	end

	if next(wienChatFilterDB.ignoreKeywords) == nil then
		return false
	end

	local message = arg1
	local userName = arg2
	local channelName = arg4 == "" and "常规" or arg4

	for _, keyword in wienChatFilterDB.ignoreKeywords do
		if (string.find(string.lower(message), string.lower(keyword)) or "*" == keyword) then
			if wienChatFilterDB.debug then
				--print("|cff00ffff[调用栈]:|r" .. debugstack(2))  -- https://wowpedia.fandom.com/wiki/API_debugstack
				print("[".. event .. "]发现用户[" .. userName .. "]在频道[" .. channelName .. "]发送待过滤的消息.匹配的关键字是:" .. keyword)
			end
			return true
		end
	end

	return false
end

local function SubscribeMessage(event)
	if not wienChatFilterDB.enabled then
		return
	end

	if next(wienChatFilterDB.subscribeKeywords) == nil then
		return
	end

	local message = arg1
	local userName = arg2
	local channelName = arg4 == "" and "常规" or arg4

	for _, item in wienChatFilterDB.subscribeKeywords do
		local keywords = SimilarKeywords[item] == nil and {item} or SimilarKeywords[item]
		for __, keyword in keywords do
			if (string.find(string.lower(message), string.lower(keyword)) or "*" == keyword) then
				local userNameUrl = string.format("|Hplayer:%s|h[%s]|h", userName, userName)
				local subMsg = "[".. channelName .. "] " .. userNameUrl .. ":  |CFF33AAFF" .. message

				print(subMsg, false, UIErrorsFrame)

				for _, cf in ChatFrames do
					print(subMsg, false, cf)
				end
				
				return
			end
		end
	end
end


local function My_ChatFrame_OnEvent(event)
	if event == "CHAT_MSG_SAY" or event == "CHAT_MSG_YELL" or event == "CHAT_MSG_CHANNEL" then
		local isIgnore = IgnoreMessage(event)
		if isIgnore then
			return
		end
	end
    source_ChatFrame_OnEvent(event)
end



f:RegisterEvent("VARIABLES_LOADED")
f:RegisterEvent("ADDON_LOADED")

f:RegisterEvent("CHAT_MSG_SAY")
f:RegisterEvent("CHAT_MSG_YELL")
f:RegisterEvent("CHAT_MSG_GUILD")
f:RegisterEvent("CHAT_MSG_CHANNEL")

f:SetScript("OnEvent", function()
    if event == "ADDON_LOADED" and arg1 == "wienChatFilter" then
		Init()
		source_ChatFrame_OnEvent = ChatFrame_OnEvent
		ChatFrame_OnEvent = My_ChatFrame_OnEvent
		this:UnregisterEvent("ADDON_LOADED")
	elseif event == "VARIABLES_LOADED" then
		Status()
		WriteText()
	else
		local isIgnore = IgnoreMessage(event)
		if isIgnore then
			return
		end
		SubscribeMessage(event)
    end
end)

f:SetScript("OnMouseUp", function()
	Toggle()
	Status() 
	WriteText()
end)

